﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using IPC.Communication.BasicFramework;
using IPC.Communication.Core;

namespace IPC.Communication.Profinet.Keyence
{
    public class KeyenceNanoHelper
    {
        public static byte[] GetConnectCmd(byte station, bool useStation)
        {
            return useStation ? Encoding.ASCII.GetBytes(String.Format("CR {0:D2}\r", station)) : Encoding.ASCII.GetBytes("CR\r");
        }

        public static byte[] GetDisConnectCmd(byte station, bool useStation)
        {
            return Encoding.ASCII.GetBytes("CQ\r");
        }

        public static int GetWordAddressMultiple(string type)
        {
            if (type == "CTH" || type == "CTC" || type == "C" || type == "T" || type == "TS" || type == "TC" || type == "CS" || type == "CC" || type == "AT")
            {
                return 2;
            }
            if (type == "DM" || type == "CM" || type == "TM" || type == "EM" || type == "FM" || type == "Z" || type == "W" || type == "ZF" || type == "VM")
            {
                return 1;
            }
            return 1;
        }

        public static OperateResult<byte[]> BuildReadCommand(string address, ushort length)
        {
            OperateResult<string, int> operateResult = KvAnalysisAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            if (length > 1)
            {
                length = (ushort)((int)length / GetWordAddressMultiple(operateResult.Content1));
            }
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("RDS");
            stringBuilder.Append(" ");
            stringBuilder.Append(operateResult.Content1);
            stringBuilder.Append(operateResult.Content2.ToString());
            stringBuilder.Append(" ");
            stringBuilder.Append(length.ToString());
            stringBuilder.Append("\r");
            byte[] bytes = Encoding.ASCII.GetBytes(stringBuilder.ToString());
            return OperateResult.CreateSuccessResult(bytes);
        }

        public static OperateResult<byte[]> BuildWriteCommand(string address, byte[] value)
        {
            OperateResult<string, int> operateResult = KvAnalysisAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("WRS");
            stringBuilder.Append(" ");
            stringBuilder.Append(operateResult.Content1);
            stringBuilder.Append(operateResult.Content2);
            stringBuilder.Append(" ");
            int num = value.Length / (GetWordAddressMultiple(operateResult.Content1) * 2);
            stringBuilder.Append(num.ToString());
            for (int i = 0; i < num; i++)
            {
                stringBuilder.Append(" ");
                stringBuilder.Append(BitConverter.ToUInt16(value, i * GetWordAddressMultiple(operateResult.Content1) * 2));
            }
            stringBuilder.Append("\r");
            return OperateResult.CreateSuccessResult(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
        }

        public static OperateResult<byte[]> BuildWriteExpansionMemoryCommand(byte unit, ushort address, byte[] value)
        {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("UWR");
            stringBuilder.Append(" ");
            stringBuilder.Append(unit);
            stringBuilder.Append(" ");
            stringBuilder.Append(address);
            stringBuilder.Append(".U");
            stringBuilder.Append(" ");
            int num = value.Length / 2;
            stringBuilder.Append(num.ToString());
            for (int i = 0; i < num; i++)
            {
                stringBuilder.Append(" ");
                stringBuilder.Append(BitConverter.ToUInt16(value, i * 2));
            }
            stringBuilder.Append("\r");
            return OperateResult.CreateSuccessResult(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
        }

        public static OperateResult<byte[]> BuildWriteCommand(string address, bool value)
        {
            OperateResult<string, int> operateResult = KvAnalysisAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            StringBuilder stringBuilder = new StringBuilder();
            if (value)
            {
                stringBuilder.Append("ST");
            }
            else
            {
                stringBuilder.Append("RS");
            }
            stringBuilder.Append(" ");
            stringBuilder.Append(operateResult.Content1);
            stringBuilder.Append(operateResult.Content2);
            stringBuilder.Append("\r");
            return OperateResult.CreateSuccessResult(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
        }

        public static OperateResult<byte[]> BuildWriteCommand(string address, bool[] value)
        {
            OperateResult<string, int> operateResult = KvAnalysisAddress(address);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append("WRS");
            stringBuilder.Append(" ");
            stringBuilder.Append(operateResult.Content1);
            stringBuilder.Append(operateResult.Content2);
            stringBuilder.Append(" ");
            stringBuilder.Append(value.Length.ToString());
            for (int i = 0; i < value.Length; i++)
            {
                stringBuilder.Append(" ");
                stringBuilder.Append(value[i] ? "1" : "0");
            }
            stringBuilder.Append("\r");
            return OperateResult.CreateSuccessResult(Encoding.ASCII.GetBytes(stringBuilder.ToString()));
        }

        private static string GetErrorText(string err)
        {
            if (err.StartsWith("E0"))
            {
                return StringResources.Language.KeyenceNanoE0;
            }
            if (err.StartsWith("E1"))
            {
                return StringResources.Language.KeyenceNanoE1;
            }
            if (err.StartsWith("E2"))
            {
                return StringResources.Language.KeyenceNanoE2;
            }
            if (err.StartsWith("E4"))
            {
                return StringResources.Language.KeyenceNanoE4;
            }
            if (err.StartsWith("E5"))
            {
                return StringResources.Language.KeyenceNanoE5;
            }
            if (err.StartsWith("E6"))
            {
                return StringResources.Language.KeyenceNanoE6;
            }
            return StringResources.Language.UnknownError + " " + err;
        }

        public static OperateResult CheckPlcReadResponse(byte[] ack)
        {
            if (ack.Length == 0)
            {
                return new OperateResult(StringResources.Language.MelsecFxReceiveZero);
            }
            if (ack[0] == 69)
            {
                return new OperateResult(GetErrorText(Encoding.ASCII.GetString(ack)));
            }
            if (ack[ack.Length - 1] != 10 && ack[ack.Length - 2] != 13)
            {
                return new OperateResult(StringResources.Language.MelsecFxAckWrong + " Actual: " + SoftBasic.ByteToHexString(ack, ' '));
            }
            return OperateResult.CreateSuccessResult();
        }

        public static OperateResult CheckPlcWriteResponse(byte[] ack)
        {
            if (ack.Length == 0)
            {
                return new OperateResult(StringResources.Language.MelsecFxReceiveZero);
            }
            if (ack[0] == 79 && ack[1] == 75)
            {
                return OperateResult.CreateSuccessResult();
            }
            return new OperateResult(GetErrorText(Encoding.ASCII.GetString(ack)));
        }

        public static OperateResult<bool[]> ExtractActualBoolData(string addressType, byte[] response)
        {
            try
            {
                if (string.IsNullOrEmpty(addressType))
                {
                    addressType = "R";
                }
                string @string = Encoding.Default.GetString(response.RemoveLast(2));
                int num;
                switch (addressType)
                {
                    default:
                        num = ((addressType == "VB") ? 1 : 0);
                        break;
                    case "R":
                    case "CR":
                    case "MR":
                    case "LR":
                    case "B":
                        num = 1;
                        break;
                }
                if (num != 0)
                {
                    return OperateResult.CreateSuccessResult((from m in @string.Split(new char[1]
					{
						' '
					}, StringSplitOptions.RemoveEmptyEntries)
                                                              select m == "1").ToArray());
                }
                if (addressType == "T" || addressType == "C" || addressType == "CTH" || addressType == "CTC")
                {
                    return OperateResult.CreateSuccessResult((from m in @string.Split(new char[1]
					{
						' '
					}, StringSplitOptions.RemoveEmptyEntries)
                                                              select m.StartsWith("1")).ToArray());
                }
                return new OperateResult<bool[]>(StringResources.Language.NotSupportedDataType);
            }
            catch (Exception ex)
            {
                OperateResult<bool[]> operateResult = new OperateResult<bool[]>();
                operateResult.Message = "Extract Msg：" + ex.Message + Environment.NewLine + "Data: " + SoftBasic.ByteToHexString(response);
                return operateResult;
            }
        }

        public static OperateResult<byte[]> ExtractActualData(string addressType, byte[] response)
        {
            try
            {
                if (string.IsNullOrEmpty(addressType))
                {
                    addressType = "R";
                }
                string @string = Encoding.Default.GetString(response.RemoveLast(2));
                string[] array = @string.Split(new char[1]
			{
				' '
			}, StringSplitOptions.RemoveEmptyEntries);
                int num;
                switch (addressType)
                {
                    default:
                        num = ((addressType == "VM") ? 1 : 0);
                        break;
                    case "DM":
                    case "EM":
                    case "FM":
                    case "ZF":
                    case "W":
                    case "TM":
                    case "Z":
                    case "CM":
                        num = 1;
                        break;
                }
                if (num != 0)
                {
                    byte[] array2 = new byte[array.Length * 2];
                    for (int i = 0; i < array.Length; i++)
                    {
                        BitConverter.GetBytes(ushort.Parse(array[i])).CopyTo(array2, i * 2);
                    }
                    return OperateResult.CreateSuccessResult(array2);
                }
                if (addressType == "AT" || addressType == "TC" || addressType == "CC" || addressType == "TS" || addressType == "CS")
                {
                    byte[] array3 = new byte[array.Length * 4];
                    for (int j = 0; j < array.Length; j++)
                    {
                        BitConverter.GetBytes(uint.Parse(array[j])).CopyTo(array3, j * 4);
                    }
                    return OperateResult.CreateSuccessResult(array3);
                }
                if (addressType == "T" || addressType == "C" || addressType == "CTH" || addressType == "CTC")
                {
                    byte[] array4 = new byte[array.Length * 4];
                    for (int k = 0; k < array.Length; k++)
                    {
                        string[] array5 = array[k].Split(new char[1]
					{
						','
					}, StringSplitOptions.RemoveEmptyEntries);
                        BitConverter.GetBytes(uint.Parse(array5[1])).CopyTo(array4, k * 4);
                    }
                    return OperateResult.CreateSuccessResult(array4);
                }
                return new OperateResult<byte[]>(StringResources.Language.NotSupportedDataType);
            }
            catch (Exception ex)
            {
                OperateResult<byte[]> operateResult = new OperateResult<byte[]>();
                operateResult.Message = "Extract Msg：" + ex.Message + Environment.NewLine + "Data: " + SoftBasic.ByteToHexString(response);
                return operateResult;
            }
        }

        public static OperateResult<string, int> KvAnalysisAddress(string address)
        {
            try
            {
                if (address.StartsWith("CTH") || address.StartsWith("cth"))
                {
                    return OperateResult.CreateSuccessResult("CTH", int.Parse(address.Substring(3)));
                }
                if (address.StartsWith("CTC") || address.StartsWith("ctc"))
                {
                    return OperateResult.CreateSuccessResult("CTC", int.Parse(address.Substring(3)));
                }
                if (address.StartsWith("CR") || address.StartsWith("cr"))
                {
                    return OperateResult.CreateSuccessResult("CR", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("MR") || address.StartsWith("mr"))
                {
                    return OperateResult.CreateSuccessResult("MR", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("LR") || address.StartsWith("lr"))
                {
                    return OperateResult.CreateSuccessResult("LR", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("DM") || address.StartsWith("DM"))
                {
                    return OperateResult.CreateSuccessResult("DM", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("CM") || address.StartsWith("cm"))
                {
                    return OperateResult.CreateSuccessResult("CM", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("W") || address.StartsWith("w"))
                {
                    return OperateResult.CreateSuccessResult("W", int.Parse(address.Substring(1)));
                }
                if (address.StartsWith("TM") || address.StartsWith("tm"))
                {
                    return OperateResult.CreateSuccessResult("TM", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("VM") || address.StartsWith("vm"))
                {
                    return OperateResult.CreateSuccessResult("VM", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("EM") || address.StartsWith("em"))
                {
                    return OperateResult.CreateSuccessResult("EM", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("FM") || address.StartsWith("fm"))
                {
                    return OperateResult.CreateSuccessResult("EM", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("ZF") || address.StartsWith("zf"))
                {
                    return OperateResult.CreateSuccessResult("ZF", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("AT") || address.StartsWith("at"))
                {
                    return OperateResult.CreateSuccessResult("AT", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("TS") || address.StartsWith("ts"))
                {
                    return OperateResult.CreateSuccessResult("TS", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("TC") || address.StartsWith("tc"))
                {
                    return OperateResult.CreateSuccessResult("TC", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("CC") || address.StartsWith("cc"))
                {
                    return OperateResult.CreateSuccessResult("CC", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("CS") || address.StartsWith("cs"))
                {
                    return OperateResult.CreateSuccessResult("CS", int.Parse(address.Substring(2)));
                }
                if (address.StartsWith("Z") || address.StartsWith("z"))
                {
                    return OperateResult.CreateSuccessResult("Z", int.Parse(address.Substring(1)));
                }
                if (address.StartsWith("R") || address.StartsWith("r"))
                {
                    return OperateResult.CreateSuccessResult("", int.Parse(address.Substring(1)));
                }
                if (address.StartsWith("B") || address.StartsWith("b"))
                {
                    return OperateResult.CreateSuccessResult("B", int.Parse(address.Substring(1)));
                }
                if (address.StartsWith("T") || address.StartsWith("t"))
                {
                    return OperateResult.CreateSuccessResult("T", int.Parse(address.Substring(1)));
                }
                if (!address.StartsWith("C") && !address.StartsWith("c"))
                {
                    throw new Exception(StringResources.Language.NotSupportedDataType);
                }
                return OperateResult.CreateSuccessResult("C", int.Parse(address.Substring(1)));
            }
            catch (Exception ex)
            {
                return new OperateResult<string, int>(ex.Message);
            }
        }

        public static OperateResult<byte[]> Read(IReadWriteDevice keyence, string address, ushort length)
        {
            if (address.StartsWith("unit="))
            {
                byte unit = (byte)HslHelper.ExtractParameter(ref address, "unit", 0);
                ushort _ = 0;
                if (!ushort.TryParse(address, out _))
                {
                    return new OperateResult<byte[]>("Address is not right, convert ushort wrong!");
                }
                return ReadExpansionMemory(keyence, unit, ushort.Parse(address), length);
            }
            OperateResult<byte[]> operateResult = BuildReadCommand(address, length);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = keyence.ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult2);
            }
            OperateResult operateResult3 = CheckPlcReadResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult3);
            }
            OperateResult<string, int> operateResult4 = KvAnalysisAddress(address);
            if (!operateResult4.IsSuccess)
            {
                return OperateResult.CreateFailedResult<byte[]>(operateResult4);
            }
            return ExtractActualData(operateResult4.Content1, operateResult2.Content);
        }

        public static OperateResult Write(IReadWriteDevice keyence, string address, byte[] value)
        {
            OperateResult<byte[]> operateResult = BuildWriteCommand(address, value);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = keyence.ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult operateResult3 = CheckPlcWriteResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            return OperateResult.CreateSuccessResult();
        }

        //[AsyncStateMachine(typeof(<ReadAsync>d__16))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<byte[]>> ReadAsync(IReadWriteDevice keyence, string address, ushort length)
        //{
        //    <ReadAsync>d__16 stateMachine = new <ReadAsync>d__16();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte[]>>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__17))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult> WriteAsync(IReadWriteDevice keyence, string address, byte[] value)
        //{
        //    <WriteAsync>d__17 stateMachine = new <WriteAsync>d__17();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public static OperateResult<bool[]> ReadBool(IReadWriteDevice keyence, string address, ushort length)
        {
            OperateResult<byte[]> operateResult = BuildReadCommand(address, length);
            if (!operateResult.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult);
            }
            OperateResult<byte[]> operateResult2 = keyence.ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult2);
            }
            OperateResult operateResult3 = CheckPlcReadResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult3);
            }
            OperateResult<string, int> operateResult4 = KvAnalysisAddress(address);
            if (!operateResult4.IsSuccess)
            {
                return OperateResult.CreateFailedResult<bool[]>(operateResult4);
            }
            return ExtractActualBoolData(operateResult4.Content1, operateResult2.Content);
        }

        public static OperateResult Write(IReadWriteDevice keyence, string address, bool value)
        {
            OperateResult<byte[]> operateResult = BuildWriteCommand(address, value);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = keyence.ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult operateResult3 = CheckPlcWriteResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            return OperateResult.CreateSuccessResult();
        }

        public static OperateResult Write(IReadWriteDevice keyence, string address, bool[] value)
        {
            OperateResult<byte[]> operateResult = BuildWriteCommand(address, value);
            if (!operateResult.IsSuccess)
            {
                return operateResult;
            }
            OperateResult<byte[]> operateResult2 = keyence.ReadFromCoreServer(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2;
            }
            OperateResult operateResult3 = CheckPlcWriteResponse(operateResult2.Content);
            if (!operateResult3.IsSuccess)
            {
                return operateResult3;
            }
            return OperateResult.CreateSuccessResult();
        }

        //[AsyncStateMachine(typeof(<ReadBoolAsync>d__21))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<bool[]>> ReadBoolAsync(IReadWriteDevice keyence, string address, ushort length)
        //{
        //    <ReadBoolAsync>d__21 stateMachine = new <ReadBoolAsync>d__21();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<bool[]>>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__22))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult> WriteAsync(IReadWriteDevice keyence, string address, bool value)
        //{
        //    <WriteAsync>d__22 stateMachine = new <WriteAsync>d__22();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        //[AsyncStateMachine(typeof(<WriteAsync>d__23))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult> WriteAsync(IReadWriteDevice keyence, string address, bool[] value)
        //{
        //    <WriteAsync>d__23 stateMachine = new <WriteAsync>d__23();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        internal static OperateResult<KeyencePLCS> ReadPlcType(IReadWriteDevice keyence)
        {
            OperateResult<byte[]> operateResult = keyence.ReadFromCoreServer(Encoding.ASCII.GetBytes("?K\r"));
            if (!operateResult.IsSuccess)
            {
                return operateResult.ConvertFailed<KeyencePLCS>();
            }
            OperateResult operateResult2 = CheckPlcReadResponse(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2.ConvertFailed<KeyencePLCS>();
            }
            string @string = Encoding.ASCII.GetString(operateResult.Content.RemoveLast(2));
            switch (@string)
            {
                case "48":
                case "49":
                    return OperateResult.CreateSuccessResult(KeyencePLCS.KV700);
                case "50":
                    return OperateResult.CreateSuccessResult(KeyencePLCS.KV1000);
                case "51":
                    return OperateResult.CreateSuccessResult(KeyencePLCS.KV3000);
                case "52":
                    return OperateResult.CreateSuccessResult(KeyencePLCS.KV5000);
                case "53":
                    return OperateResult.CreateSuccessResult(KeyencePLCS.KV5500);
                default:
                    return new OperateResult<KeyencePLCS>("Unknow type:" + @string);
            }
        }

        //[AsyncStateMachine(typeof(<ReadPlcTypeAsync>d__25))]
        //[DebuggerStepThrough]
        //internal static Task<OperateResult<KeyencePLCS>> ReadPlcTypeAsync(IReadWriteDevice keyence)
        //{
        //    <ReadPlcTypeAsync>d__25 stateMachine = new <ReadPlcTypeAsync>d__25();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<KeyencePLCS>>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        internal static OperateResult<int> ReadPlcMode(IReadWriteDevice keyence)
        {
            OperateResult<byte[]> operateResult = keyence.ReadFromCoreServer(Encoding.ASCII.GetBytes("?M\r"));
            if (!operateResult.IsSuccess)
            {
                return operateResult.ConvertFailed<int>();
            }
            OperateResult operateResult2 = CheckPlcReadResponse(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2.ConvertFailed<int>();
            }
            string @string = Encoding.ASCII.GetString(operateResult.Content.RemoveLast(2));
            if (@string == "0")
            {
                return OperateResult.CreateSuccessResult(0);
            }
            return OperateResult.CreateSuccessResult(1);
        }

        //[AsyncStateMachine(typeof(<ReadPlcModeAsync>d__27))]
        //[DebuggerStepThrough]
        //internal static Task<OperateResult<int>> ReadPlcModeAsync(IReadWriteDevice keyence)
        //{
        //    <ReadPlcModeAsync>d__27 stateMachine = new <ReadPlcModeAsync>d__27();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<int>>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public static OperateResult SetPlcDateTime(IReadWriteDevice keyence, DateTime dateTime)
        {
            OperateResult<byte[]> operateResult = keyence.ReadFromCoreServer(Encoding.ASCII.GetBytes(String.Format("WRT {0:D2} {1:D2} {2:D2} ", dateTime.Year - 2000, dateTime.Month, dateTime.Day) + String.Format("{0:D2} {1:D2} {2:D2} {3}\r", dateTime.Hour, dateTime.Minute, dateTime.Second, (int)dateTime.DayOfWeek)));
            if (!operateResult.IsSuccess)
            {
                return operateResult.ConvertFailed<int>();
            }
            return CheckPlcWriteResponse(operateResult.Content);
        }

        //[AsyncStateMachine(typeof(<SetPlcDateTimeAsync>d__29))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult> SetPlcDateTimeAsync(IReadWriteDevice keyence, DateTime dateTime)
        //{
        //    <SetPlcDateTimeAsync>d__29 stateMachine = new <SetPlcDateTimeAsync>d__29();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.dateTime = dateTime;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public static OperateResult<string> ReadAddressAnnotation(IReadWriteDevice keyence, string address)
        {
            OperateResult<byte[]> operateResult = keyence.ReadFromCoreServer(Encoding.ASCII.GetBytes("RDC " + address + "\r"));
            if (!operateResult.IsSuccess)
            {
                return operateResult.ConvertFailed<string>();
            }
            OperateResult operateResult2 = CheckPlcReadResponse(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2.ConvertFailed<string>();
            }
            return OperateResult.CreateSuccessResult(Encoding.ASCII.GetString(operateResult.Content.RemoveLast(2)).Trim(' '));
        }

        //[AsyncStateMachine(typeof(<ReadAddressAnnotationAsync>d__31))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<string>> ReadAddressAnnotationAsync(IReadWriteDevice keyence, string address)
        //{
        //    <ReadAddressAnnotationAsync>d__31 stateMachine = new <ReadAddressAnnotationAsync>d__31();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<string>>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.address = address;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public static OperateResult<byte[]> ReadExpansionMemory(IReadWriteDevice keyence, byte unit, ushort address, ushort length)
        {
            OperateResult<byte[]> operateResult = keyence.ReadFromCoreServer(Encoding.ASCII.GetBytes(String.Format("URD {0} {1}.U {2}\r", unit, address, length)));
            if (!operateResult.IsSuccess)
            {
                return operateResult.ConvertFailed<byte[]>();
            }
            OperateResult operateResult2 = CheckPlcReadResponse(operateResult.Content);
            if (!operateResult2.IsSuccess)
            {
                return operateResult2.ConvertFailed<byte[]>();
            }
            return ExtractActualData("DM", operateResult.Content);
        }

        //[AsyncStateMachine(typeof(<ReadExpansionMemoryAsync>d__33))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult<byte[]>> ReadExpansionMemoryAsync(IReadWriteDevice keyence, byte unit, ushort address, ushort length)
        //{
        //    <ReadExpansionMemoryAsync>d__33 stateMachine = new <ReadExpansionMemoryAsync>d__33();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult<byte[]>>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.unit = unit;
        //    stateMachine.address = address;
        //    stateMachine.length = length;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}

        public static OperateResult WriteExpansionMemory(IReadWriteDevice keyence, byte unit, ushort address, byte[] value)
        {
            OperateResult<byte[]> operateResult = keyence.ReadFromCoreServer(BuildWriteExpansionMemoryCommand(unit, address, value).Content);
            if (!operateResult.IsSuccess)
            {
                return operateResult.ConvertFailed<byte[]>();
            }
            return CheckPlcWriteResponse(operateResult.Content);
        }

        //[AsyncStateMachine(typeof(<WriteExpansionMemoryAsync>d__35))]
        //[DebuggerStepThrough]
        //public static Task<OperateResult> WriteExpansionMemoryAsync(IReadWriteDevice keyence, byte unit, ushort address, byte[] value)
        //{
        //    <WriteExpansionMemoryAsync>d__35 stateMachine = new <WriteExpansionMemoryAsync>d__35();
        //    stateMachine.<>t__builder = AsyncTaskMethodBuilder<OperateResult>.Create();
        //    stateMachine.keyence = keyence;
        //    stateMachine.unit = unit;
        //    stateMachine.address = address;
        //    stateMachine.value = value;
        //    stateMachine.<>1__state = -1;
        //    stateMachine.<>t__builder.Start(ref stateMachine);
        //    return stateMachine.<>t__builder.Task;
        //}
    }
}